package xin.nick.demo;

import java.text.ParseException;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.Random;
import java.util.UUID;

public class IDFactory {
    public static final int idlen = 32;
    static Random random = new Random(System.currentTimeMillis());
    private static long lastTs = 0L;
    private static int count = 0;

    public IDFactory() {
    }

    public static String newUUID() {
        UUID id = UUID.randomUUID();
        return id.toString().replace("-", "");
    }

    public static synchronized String newGUID() {
        String now = DateUtils.now("yyyyMMddHHmmssSSS");
        Long number = Math.abs(random.nextLong());
        String guid = now + number;
        int len = 32 - guid.length();

        for(int i = 0; i < len; ++i) {
            guid = guid + "0";
        }

        if (guid.length() > 32) {
            guid = guid.substring(0, 32);
        }

        return guid;
    }

    public static synchronized String newNo(String prefix) {
        return prefix + newGUID().substring(prefix.length());
    }

    public static String newShortID(String node) {
        StringBuilder sb = new StringBuilder();
        sb.append(node == null ? "" : node);
        LocalDateTime nowTime = LocalDateTime.now();
        sb.append(nowTime.getYear());
        int dayOfYear = nowTime.getDayOfYear();
        if (dayOfYear < 10) {
            sb.append("00" + dayOfYear);
        } else if (dayOfYear < 100) {
            sb.append("0" + dayOfYear);
        } else {
            sb.append("" + dayOfYear);
        }

        int secondOfDay = nowTime.toLocalTime().toSecondOfDay();
        if (secondOfDay < 10) {
            sb.append("0000" + secondOfDay);
        } else if (secondOfDay < 100) {
            sb.append("000" + secondOfDay);
        } else if (secondOfDay < 1000) {
            sb.append("00" + secondOfDay);
        } else if (secondOfDay < 10000) {
            sb.append("0" + secondOfDay);
        } else {
            sb.append("" + secondOfDay);
        }

        long milliSecond = nowTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();
        String milliSecondStr = String.valueOf(milliSecond);
        sb.append(milliSecondStr.substring(milliSecondStr.length() - 3));
        count(milliSecond);
        if (count < 10) {
            sb.append("00");
        } else if (count < 100) {
            sb.append("0");
        } else if (count < 1000) {
        }

        sb.append(count);
        int i = random.nextInt(10000);
        if (i < 10) {
            sb.append("000");
        } else if (i < 100) {
            sb.append("00");
        } else if (i < 1000) {
            sb.append("0");
        } else if (i < 10000) {
        }

        sb.append(i);
        return sb.toString();
    }

    public static synchronized void count(long timestamp) {
        if (lastTs < timestamp) {
            lastTs = timestamp;
            count = 0;
        } else {
            ++count;
        }

    }

    public static void main(String[] args) throws ParseException, InterruptedException {
        String id = newShortID("01");
        System.out.println(id);
        String currentTimeMillis = System.currentTimeMillis() + "";
        LocalDateTime nowTime = LocalDateTime.now();
        System.out.println(nowTime.getNano());
        System.out.println(currentTimeMillis.substring(currentTimeMillis.length() - 3));
        System.out.println(currentTimeMillis);
        System.out.println(nowTime.toInstant(ZoneOffset.of("+8")).toEpochMilli());
    }
}

